﻿using System;
using System.Windows.Forms;
using Introducer.Properties;
using Managers.Nova;
using Managers.Nova.Introducer;
using Providers.Nova.Modules;
using Network;
using Managers;

namespace Introducer
{
    public partial class FormMain : Form
    {
        private NovaManager NovaManager { get { return NovaIntroducer.Instance.NovaManager; } }

        public FormMain()
        {
            NovaManager.OnMachineRegistered += new EventHandler<MachineRegisteredEventArgs>(OnMachineRegistered);
            NovaManager.OnIntroductionCompleted += new EventHandler<IntroductionCompletedEventArgs>(OnIntroductionCompleted);
            NovaManager.OnWrongPassword += new EventHandler<WrongPasswordEventArgs>(IntroducerManager_OnWrongPassword);
            NovaManager.OnMachineBanned += new EventHandler<MachineBannedEventArgs>(IntroducerManager_OnMachineBanned);
            NovaManager.OnKeepAliveReceived += new EventHandler<EventArgs>(IntroducerManager_OnKeepAliveReceived);
            NovaManager.OnDebugMessage += NovaManager_OnDebugMessage;
            this.Closed += FormMain_Closed;
            InitializeComponent();
        }

        private void NovaManager_OnDebugMessage(object sender, DebugMessageEventArgs e)
        {
            LogText(e.Message);
        }

        private void FormMain_Closed(object sender, EventArgs e)
        {
            NovaManager.Stop();
        }

        void IntroducerManager_OnKeepAliveReceived(object sender, EventArgs e)
        {
            //LogText(String.Format("Received KeepAlive message."));
        }

        void IntroducerManager_OnMachineBanned(object sender, MachineBannedEventArgs e)
        {
            LabelNumMachinesBanned.Text = NovaManager.Provider.MachineBanTable.Count.ToString();

            LogText(
                $"{e.BannedMachine.PublicEndPoint} ({e.BannedMachine.Identity}) has been banned for {e.NumConnectionAttempts} wrong connection attempts.");
        }

        void IntroducerManager_OnWrongPassword(object sender, WrongPasswordEventArgs e)
        {
            LogText(
                $"{e.OffendingMachine.PublicEndPoint} has provided an incorrect password {e.NumConnectionAttempts} times to {e.TargetMachine.NovaId} ({e.TargetMachine.PublicEndPoint}).");
        }

        private void OnIntroductionCompleted(object sender, IntroductionCompletedEventArgs e)
        {
            LabelNumMachinesIntroduced.Text = NovaManager.Provider.NumMachinesIntroduced.ToString();

            LogText(
                $"Introduced {e.ClientMachine.PublicEndPoint} to {e.ServerMachine.NovaId} ({e.ServerMachine.PublicEndPoint}).");
        }

        private void OnMachineRegistered(object sender, MachineRegisteredEventArgs e)
        {
            LabelNumMachinesRegistered.Text = NovaManager.Provider.NumMachinesRegistered.ToString();

            LogText($"Registered {e.Machine.PublicEndPoint} as {e.Machine.NovaId}.");
        }

        private void LogText(string text)
        {
            RichTextBoxLog.AppendText(string.Format(DateTime.Now.ToString() + " {0}" + Environment.NewLine, text));
        }

        private void MenuFile_Exit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void MenuIntroducer_Start_Click(object sender, EventArgs e)
        {
            if (NovaManager.Network.Status == NetworkStatus.Running)
            {
                MessageBox.Show(Resources.FormMain_MenuIntroducer_Start_Click_, Resources.FormMain_MenuIntroducer_Start_Click_Unable_to_Start, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                NovaManager.Restart();
                LogText("Restarted Introducer service.");
            }
        }

        private void MenuIntroducer_Stop_Click(object sender, EventArgs e)
        {
            if (NovaManager.Network.Status != NetworkStatus.Running)
            {
                MessageBox.Show("Not running.", "Unable to Stop", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else if (NovaManager.Network.Status == NetworkStatus.ShutdownRequested)
            {
                MessageBox.Show("Already shutting down.", "Unable to Stop", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                NovaManager.Stop();
                LogText("Stopped Introducer service.");
            }
        }

        private void MenuIntroducer_Status_Click(object sender, EventArgs e)
        {
            LogText("Network Status: " + NovaManager.Network.Status.ToString());
        }
    }
}
